package com.ruoyi.rabbitmq.controller;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.rabbitmq.config.RabbitMQConfig;
import com.ruoyi.rabbitmq.service.MessagePublisher;
import com.ruoyi.rabbitmq.service.RabbitMQManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * RabbitMQ管理控制器
 * 
 * @author ruoyi
 */
@RestController
@RequestMapping("/rabbitmq")
@ConditionalOnProperty(name = "spring.rabbitmq.enabled", havingValue = "true", matchIfMissing = true)
public class RabbitMQController extends BaseController
{
    @Autowired
    private MessagePublisher messagePublisher;

    @Autowired
    private RabbitMQManager rabbitMQManager;

    /**
     * 获取RabbitMQ连接信息
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:info:query')")
    @GetMapping("/info")
    public AjaxResult getConnectionInfo()
    {
        Map<String, Object> info = rabbitMQManager.getConnectionInfo();
        return AjaxResult.success(info);
    }

    /**
     * 初始化默认配置
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:config:init')")
    @Log(title = "RabbitMQ配置", businessType = BusinessType.INSERT)
    @PostMapping("/init")
    public AjaxResult initializeConfig()
    {
        try
        {
            rabbitMQManager.initializeDefaultConfig();
            return AjaxResult.success("RabbitMQ默认配置初始化成功");
        }
        catch (Exception e)
        {
            return AjaxResult.error("RabbitMQ默认配置初始化失败：" + e.getMessage());
        }
    }

    /**
     * 发送直连消息
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:message:send')")
    @Log(title = "发送直连消息", businessType = BusinessType.INSERT)
    @PostMapping("/send/direct")
    public AjaxResult sendDirectMessage(@RequestBody Map<String, Object> params)
    {
        try
        {
            Object content = params.get("content");
            String messageId = messagePublisher.sendDirectMessage(content);
            return AjaxResult.success("消息发送成功", messageId);
        }
        catch (Exception e)
        {
            return AjaxResult.error("消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 发送主题消息
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:message:send')")
    @Log(title = "发送主题消息", businessType = BusinessType.INSERT)
    @PostMapping("/send/topic")
    public AjaxResult sendTopicMessage(@RequestBody Map<String, Object> params)
    {
        try
        {
            Object content = params.get("content");
            String routingKey = (String) params.get("routingKey");
            if (routingKey == null || routingKey.isEmpty())
            {
                return AjaxResult.error("路由键不能为空");
            }
            String messageId = messagePublisher.sendTopicMessage(content, routingKey);
            return AjaxResult.success("消息发送成功", messageId);
        }
        catch (Exception e)
        {
            return AjaxResult.error("消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 发送扇形消息
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:message:send')")
    @Log(title = "发送扇形消息", businessType = BusinessType.INSERT)
    @PostMapping("/send/fanout")
    public AjaxResult sendFanoutMessage(@RequestBody Map<String, Object> params)
    {
        try
        {
            Object content = params.get("content");
            String messageId = messagePublisher.sendFanoutMessage(content);
            return AjaxResult.success("消息发送成功", messageId);
        }
        catch (Exception e)
        {
            return AjaxResult.error("消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 发送延迟消息
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:message:send')")
    @Log(title = "发送延迟消息", businessType = BusinessType.INSERT)
    @PostMapping("/send/delay")
    public AjaxResult sendDelayMessage(@RequestBody Map<String, Object> params)
    {
        try
        {
            Object content = params.get("content");
            Long delayMillis = Long.valueOf(params.get("delayMillis").toString());
            String messageId = messagePublisher.sendRetryMessage(content, delayMillis);
            return AjaxResult.success("延迟消息发送成功", messageId);
        }
        catch (Exception e)
        {
            return AjaxResult.error("延迟消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 发送带过期时间的消息
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:message:send')")
    @Log(title = "发送过期消息", businessType = BusinessType.INSERT)
    @PostMapping("/send/expiration")
    public AjaxResult sendMessageWithExpiration(@RequestBody Map<String, Object> params)
    {
        try
        {
            Object content = params.get("content");
            String exchange = (String) params.get("exchange");
            String routingKey = (String) params.get("routingKey");
            String messageType = (String) params.get("messageType");
            Long expiration = Long.valueOf(params.get("expiration").toString());

            String messageId = messagePublisher.sendMessageWithExpiration(content, exchange, routingKey, messageType, expiration);
            return AjaxResult.success("消息发送成功", messageId);
        }
        catch (Exception e)
        {
            return AjaxResult.error("消息发送失败：" + e.getMessage());
        }
    }

    /**
     * 创建队列
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:queue:create')")
    @Log(title = "创建队列", businessType = BusinessType.INSERT)
    @PostMapping("/queue/create")
    public AjaxResult createQueue(@RequestBody Map<String, Object> params)
    {
        try
        {
            String queueName = (String) params.get("queueName");
            Boolean durable = (Boolean) params.get("durable");
            Boolean exclusive = (Boolean) params.get("exclusive");
            Boolean autoDelete = (Boolean) params.get("autoDelete");
            Map<String, Object> arguments = (Map<String, Object>) params.get("arguments");

            boolean result = rabbitMQManager.createQueue(queueName, durable, exclusive, autoDelete, arguments);
            if (result)
            {
                return AjaxResult.success("队列创建成功");
            }
            else
            {
                return AjaxResult.error("队列创建失败");
            }
        }
        catch (Exception e)
        {
            return AjaxResult.error("队列创建失败：" + e.getMessage());
        }
    }

    /**
     * 创建直连交换机
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:exchange:create')")
    @Log(title = "创建直连交换机", businessType = BusinessType.INSERT)
    @PostMapping("/exchange/direct/create")
    public AjaxResult createDirectExchange(@RequestBody Map<String, Object> params)
    {
        try
        {
            String exchangeName = (String) params.get("exchangeName");
            Boolean durable = (Boolean) params.get("durable");
            Boolean autoDelete = (Boolean) params.get("autoDelete");

            boolean result = rabbitMQManager.createDirectExchange(exchangeName, durable, autoDelete);
            if (result)
            {
                return AjaxResult.success("直连交换机创建成功");
            }
            else
            {
                return AjaxResult.error("直连交换机创建失败");
            }
        }
        catch (Exception e)
        {
            return AjaxResult.error("直连交换机创建失败：" + e.getMessage());
        }
    }

    /**
     * 创建主题交换机
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:exchange:create')")
    @Log(title = "创建主题交换机", businessType = BusinessType.INSERT)
    @PostMapping("/exchange/topic/create")
    public AjaxResult createTopicExchange(@RequestBody Map<String, Object> params)
    {
        try
        {
            String exchangeName = (String) params.get("exchangeName");
            Boolean durable = (Boolean) params.get("durable");
            Boolean autoDelete = (Boolean) params.get("autoDelete");

            boolean result = rabbitMQManager.createTopicExchange(exchangeName, durable, autoDelete);
            if (result)
            {
                return AjaxResult.success("主题交换机创建成功");
            }
            else
            {
                return AjaxResult.error("主题交换机创建失败");
            }
        }
        catch (Exception e)
        {
            return AjaxResult.error("主题交换机创建失败：" + e.getMessage());
        }
    }

    /**
     * 创建扇形交换机
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:exchange:create')")
    @Log(title = "创建扇形交换机", businessType = BusinessType.INSERT)
    @PostMapping("/exchange/fanout/create")
    public AjaxResult createFanoutExchange(@RequestBody Map<String, Object> params)
    {
        try
        {
            String exchangeName = (String) params.get("exchangeName");
            Boolean durable = (Boolean) params.get("durable");
            Boolean autoDelete = (Boolean) params.get("autoDelete");

            boolean result = rabbitMQManager.createFanoutExchange(exchangeName, durable, autoDelete);
            if (result)
            {
                return AjaxResult.success("扇形交换机创建成功");
            }
            else
            {
                return AjaxResult.error("扇形交换机创建失败");
            }
        }
        catch (Exception e)
        {
            return AjaxResult.error("扇形交换机创建失败：" + e.getMessage());
        }
    }

    /**
     * 绑定队列到交换机
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:binding:create')")
    @Log(title = "绑定队列到交换机", businessType = BusinessType.INSERT)
    @PostMapping("/binding/create")
    public AjaxResult createBinding(@RequestBody Map<String, Object> params)
    {
        try
        {
            String queueName = (String) params.get("queueName");
            String exchangeName = (String) params.get("exchangeName");
            String routingKey = (String) params.get("routingKey");
            String exchangeType = (String) params.get("exchangeType");

            boolean result = false;
            switch (exchangeType)
            {
                case "direct":
                    result = rabbitMQManager.bindQueueToExchange(queueName, exchangeName, routingKey);
                    break;
                case "topic":
                    result = rabbitMQManager.bindQueueToTopicExchange(queueName, exchangeName, routingKey);
                    break;
                case "fanout":
                    result = rabbitMQManager.bindQueueToFanoutExchange(queueName, exchangeName);
                    break;
                default:
                    return AjaxResult.error("不支持的交换机类型");
            }

            if (result)
            {
                return AjaxResult.success("绑定创建成功");
            }
            else
            {
                return AjaxResult.error("绑定创建失败");
            }
        }
        catch (Exception e)
        {
            return AjaxResult.error("绑定创建失败：" + e.getMessage());
        }
    }

    /**
     * 删除队列
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:queue:delete')")
    @Log(title = "删除队列", businessType = BusinessType.DELETE)
    @DeleteMapping("/queue/{queueName}")
    public AjaxResult deleteQueue(@PathVariable String queueName)
    {
        try
        {
            boolean result = rabbitMQManager.deleteQueue(queueName);
            if (result)
            {
                return AjaxResult.success("队列删除成功");
            }
            else
            {
                return AjaxResult.error("队列删除失败");
            }
        }
        catch (Exception e)
        {
            return AjaxResult.error("队列删除失败：" + e.getMessage());
        }
    }

    /**
     * 删除交换机
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:exchange:delete')")
    @Log(title = "删除交换机", businessType = BusinessType.DELETE)
    @DeleteMapping("/exchange/{exchangeName}")
    public AjaxResult deleteExchange(@PathVariable String exchangeName)
    {
        try
        {
            boolean result = rabbitMQManager.deleteExchange(exchangeName);
            if (result)
            {
                return AjaxResult.success("交换机删除成功");
            }
            else
            {
                return AjaxResult.error("交换机删除失败");
            }
        }
        catch (Exception e)
        {
            return AjaxResult.error("交换机删除失败：" + e.getMessage());
        }
    }

    /**
     * 解绑队列和交换机
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:binding:delete')")
    @Log(title = "解绑队列和交换机", businessType = BusinessType.DELETE)
    @DeleteMapping("/binding")
    public AjaxResult deleteBinding(@RequestBody Map<String, Object> params)
    {
        try
        {
            String queueName = (String) params.get("queueName");
            String exchangeName = (String) params.get("exchangeName");
            String routingKey = (String) params.get("routingKey");

            boolean result = rabbitMQManager.unbindQueueFromExchange(queueName, exchangeName, routingKey);
            if (result)
            {
                return AjaxResult.success("解绑成功");
            }
            else
            {
                return AjaxResult.error("解绑失败");
            }
        }
        catch (Exception e)
        {
            return AjaxResult.error("解绑失败：" + e.getMessage());
        }
    }

    /**
     * 创建带死信队列的队列
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:queue:create')")
    @Log(title = "创建死信队列", businessType = BusinessType.INSERT)
    @PostMapping("/queue/dead-letter/create")
    public AjaxResult createQueueWithDeadLetter(@RequestBody Map<String, Object> params)
    {
        try
        {
            String queueName = (String) params.get("queueName");
            String deadLetterExchange = (String) params.get("deadLetterExchange");
            String deadLetterRoutingKey = (String) params.get("deadLetterRoutingKey");

            boolean result = rabbitMQManager.createQueueWithDeadLetter(queueName, deadLetterExchange, deadLetterRoutingKey);
            if (result)
            {
                return AjaxResult.success("带死信队列的队列创建成功");
            }
            else
            {
                return AjaxResult.error("带死信队列的队列创建失败");
            }
        }
        catch (Exception e)
        {
            return AjaxResult.error("带死信队列的队列创建失败：" + e.getMessage());
        }
    }

    /**
     * 创建延迟队列
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:queue:create')")
    @Log(title = "创建延迟队列", businessType = BusinessType.INSERT)
    @PostMapping("/queue/delay/create")
    public AjaxResult createDelayQueue(@RequestBody Map<String, Object> params)
    {
        try
        {
            String queueName = (String) params.get("queueName");
            Long delayMillis = Long.valueOf(params.get("delayMillis").toString());
            String targetExchange = (String) params.get("targetExchange");
            String targetRoutingKey = (String) params.get("targetRoutingKey");

            boolean result = rabbitMQManager.createDelayQueue(queueName, delayMillis, targetExchange, targetRoutingKey);
            if (result)
            {
                return AjaxResult.success("延迟队列创建成功");
            }
            else
            {
                return AjaxResult.error("延迟队列创建失败");
            }
        }
        catch (Exception e)
        {
            return AjaxResult.error("延迟队列创建失败：" + e.getMessage());
        }
    }

    /**
     * 获取默认配置信息
     */
    @PreAuthorize("@ss.hasPermi('rabbitmq:info:query')")
    @GetMapping("/config/default")
    public AjaxResult getDefaultConfig()
    {
        Map<String, Object> config = new HashMap<>();
        config.put("directExchange", RabbitMQConfig.DIRECT_EXCHANGE);
        config.put("topicExchange", RabbitMQConfig.TOPIC_EXCHANGE);
        config.put("fanoutExchange", RabbitMQConfig.FANOUT_EXCHANGE);
        config.put("deadLetterExchange", RabbitMQConfig.DEAD_LETTER_EXCHANGE);
        config.put("directQueue", RabbitMQConfig.DIRECT_QUEUE);
        config.put("topicQueue1", RabbitMQConfig.TOPIC_QUEUE_1);
        config.put("topicQueue2", RabbitMQConfig.TOPIC_QUEUE_2);
        config.put("fanoutQueue1", RabbitMQConfig.FANOUT_QUEUE_1);
        config.put("fanoutQueue2", RabbitMQConfig.FANOUT_QUEUE_2);
        config.put("deadLetterQueue", RabbitMQConfig.DEAD_LETTER_QUEUE);
        config.put("retryQueue", RabbitMQConfig.RETRY_QUEUE);
        config.put("directRoutingKey", RabbitMQConfig.DIRECT_ROUTING_KEY);
        config.put("topicRoutingKey1", RabbitMQConfig.TOPIC_ROUTING_KEY_1);
        config.put("topicRoutingKey2", RabbitMQConfig.TOPIC_ROUTING_KEY_2);
        config.put("deadLetterRoutingKey", RabbitMQConfig.DEAD_LETTER_ROUTING_KEY);
        
        return AjaxResult.success(config);
    }
} 